import 'dart:convert';

import 'package:equatable/equatable.dart';
import 'package:backend.purchases/domain/entities/app_store_api/app_store_api_purchased_subscription_renewal_info.dart';
import 'package:backend.purchases/infrastructure/dtos/app_store_api/app_store_api_environment_dto.dart';
import 'package:backend.purchases/infrastructure/dtos/app_store_api/app_store_api_expiration_reason_dto.dart';
import 'package:backend.purchases/infrastructure/dtos/app_store_api/app_store_api_price_increase_status_dto.dart';

const kAppStoreApiPurchasedSubscriptionRenewalInfoPurchaseItemSkuKey = 'productId';
const kAppStoreApiPurchasedSubscriptionRenewalInfoOriginalTransactionIdKey =
    'originalTransactionId';
const kAppStoreApiPurchasedSubscriptionRenewalInfoAutoRenewalStatusKey = 'autoRenewStatus';
const kAppStoreApiPurchasedSubscriptionRenewalInfoIsInBillingRetryPeriodKey =
    'isInBillingRetryPeriod';
const kAppStoreApiPurchasedSubscriptionRenewalInfoPriceIncreaseStatusKey = 'priceIncreaseStatus';
const kAppStoreApiPurchasedSubscriptionRenewalInfoEnvironmentKey = 'environment';
const kAppStoreApiPurchasedSubscriptionRenewalInfoExpirationReasonKey = 'expirationIntent';
const kAppStoreApiPurchasedSubscriptionRenewalInfoGracePeriodExpirationTimeMsKey =
    'gracePeriodExpiresDate';

final _jsonBase64 = json.fuse(utf8.fuse(base64Url));

String _padBase64(String value) {
  final lenght = value.length;

  switch (lenght % 4) {
    case 2:
      return value.padRight(lenght + 2, '=');
    case 3:
      return value.padRight(lenght + 1, '=');
    default:
      return value;
  }
}

class AppStoreApiPurchasedSubscriptionRenewalInfoDto extends Equatable {
  const AppStoreApiPurchasedSubscriptionRenewalInfoDto._internal({
    required this.purchaseItemSku,
    required this.originalTransactionId,
    required this.autoRenewalEnabled,
    required this.isInBillingRetryPeriod,
    required this.priceIncreaseStatusDto,
    required this.environmentDto,
    required this.expirationReasonDto,
    required this.gracePeriodExpirationTimeMs,
  });

  final String purchaseItemSku;
  final String originalTransactionId;
  final bool autoRenewalEnabled;
  final bool isInBillingRetryPeriod;
  final AppStoreApiPurchasedSubscriptionPriceIncreaseStatusDto priceIncreaseStatusDto;
  final AppStoreApiEnvironmentDto environmentDto;
  final AppStoreApiExpirationReasonDto? expirationReasonDto;
  final int? gracePeriodExpirationTimeMs;

  @override
  List<Object?> get props {
    return [
      purchaseItemSku,
      originalTransactionId,
      autoRenewalEnabled,
      isInBillingRetryPeriod,
      priceIncreaseStatusDto,
      environmentDto,
      expirationReasonDto,
      gracePeriodExpirationTimeMs,
    ];
  }

  factory AppStoreApiPurchasedSubscriptionRenewalInfoDto._fromJson(Map<String, dynamic> json) {
    final autoRenewalStatus =
        json[kAppStoreApiPurchasedSubscriptionRenewalInfoAutoRenewalStatusKey];
    final autoRenewalEnabled = autoRenewalStatus == 1;

    final isInBillingRetryPeriodData =
        json[kAppStoreApiPurchasedSubscriptionRenewalInfoIsInBillingRetryPeriodKey] as bool?;
    final isInBillingRetryPeriod = isInBillingRetryPeriodData == true;

    final priceIncreaseStatusCode =
        json[kAppStoreApiPurchasedSubscriptionRenewalInfoPriceIncreaseStatusKey];
    final priceIncreaseStatusDto =
        AppStoreApiPurchasedSubscriptionPriceIncreaseStatusDto.fromCode(priceIncreaseStatusCode);

    final environmentString = json[kAppStoreApiPurchasedSubscriptionRenewalInfoEnvironmentKey];
    final environmentDto = AppStoreApiEnvironmentDto.fromString(environmentString);

    final expirationReasonCode =
        json[kAppStoreApiPurchasedSubscriptionRenewalInfoExpirationReasonKey];
    AppStoreApiExpirationReasonDto? expirationReasonDto;

    if (expirationReasonCode != null) {
      expirationReasonDto = AppStoreApiExpirationReasonDto.fromCode(expirationReasonCode);
    }

    return AppStoreApiPurchasedSubscriptionRenewalInfoDto._internal(
      purchaseItemSku: json[kAppStoreApiPurchasedSubscriptionRenewalInfoPurchaseItemSkuKey],
      originalTransactionId:
          json[kAppStoreApiPurchasedSubscriptionRenewalInfoOriginalTransactionIdKey],
      autoRenewalEnabled: autoRenewalEnabled,
      isInBillingRetryPeriod: isInBillingRetryPeriod,
      priceIncreaseStatusDto: priceIncreaseStatusDto,
      environmentDto: environmentDto,
      expirationReasonDto: expirationReasonDto,
      gracePeriodExpirationTimeMs:
          json[kAppStoreApiPurchasedSubscriptionRenewalInfoGracePeriodExpirationTimeMsKey],
    );
  }

  factory AppStoreApiPurchasedSubscriptionRenewalInfoDto.fromJws(String jws) {
    final parts = jws.split('.');
    final json = _jsonBase64.decode(_padBase64(parts[1])) as Map<String, dynamic>;
    return AppStoreApiPurchasedSubscriptionRenewalInfoDto._fromJson(json);
  }

  AppStoreApiPurchasedSubscriptionRenewalInfo toEntity() {
    DateTime? gracePeriodExpirationTime;

    if (gracePeriodExpirationTimeMs != null) {
      gracePeriodExpirationTime = DateTime.fromMillisecondsSinceEpoch(gracePeriodExpirationTimeMs!);
    }

    return AppStoreApiPurchasedSubscriptionRenewalInfo(
      purchaseItemSku: purchaseItemSku,
      originalTransactionId: originalTransactionId,
      autoRenewalEnabled: autoRenewalEnabled,
      isInBillingRetryPeriod: isInBillingRetryPeriod,
      priceIncreaseStatus: priceIncreaseStatusDto.toEntity(),
      environment: environmentDto.toEntity(),
      expirationReason: expirationReasonDto?.toEntity(),
      gracePeriodExpirationTime: gracePeriodExpirationTime,
    );
  }
}
